﻿using ServerCommon.Config;
using ServerCommon.Log;
using ServerCommon.Net;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GameServer.Server
{
    public class GameNet
    {
        public static readonly GameNet Instance = new Lazy<GameNet>(() => new GameNet(), true).Value;
        private static LogHelper log = LogHelper.GetLogger(typeof(GameNet));

        NetNodeManager _managerDatabase;
        NetClient _clientDatabase;

        NetNodeManager _managerGM;
        NetClient _clientGM;

        NetNodeManager _managerGateway;

        NetNodeManager _managerLogin;
        NetClient _clientLogin;

        NetNodeManager _managerWorld;
        NetClient _clientWorld;

        public void Init(long localGameId)
        {
            _managerDatabase = new NetNodeManager();
            _managerDatabase.Init();

            _managerGM = new NetNodeManager();
            _managerGM.Init();

            _managerGateway = new NetNodeManager();
            _managerGateway.Init();

            _managerLogin = new NetNodeManager();
            _managerLogin.Init();

            _managerWorld = new NetNodeManager();
            _managerWorld.Init();

            var netConfig = ConfigManager.Instance.NetConfig["NetConfigure"];
            var clientNetConfig = netConfig["ServerCustomConfig"];
            int connectionCount = clientNetConfig.Value<int>("MaxConnection");
            int bufferSize = clientNetConfig.Value<int>("SAEABufferSize");

            var serverConfig = ConfigManager.Instance.ServerConfig;
            var dataConfig = serverConfig["DatabaseServer"];
            string ip = dataConfig.Value<string>("Ip");
            int port = dataConfig.Value<int>("Port");
            long dataServerId = dataConfig.Value<long>("Id");

            _clientDatabase = new NetClient();
            _clientDatabase.Config(_managerDatabase, ip, port, connectionCount, bufferSize, dataServerId, localGameId);
            _clientDatabase.Start();
            _clientDatabase.ShowPrompt();

            var gmConfig = serverConfig["GMServer"];
            ip = gmConfig.Value<string>("Ip");
            port = gmConfig.Value<int>("Port");
            long gmServerId = gmConfig.Value<long>("Id");

            _clientGM = new NetClient();
            _clientGM.Config(_managerGM, ip, port, connectionCount, bufferSize, gmServerId, localGameId);
            _clientGM.Start();
            _clientGM.ShowPrompt();

            var gatewayConfig = serverConfig["GatewayServer"];
            ip = gatewayConfig.Value<string>("InnerIp");
            var gatewayList = gatewayConfig["List"].ToArray();
            for(int i = 0; i < gatewayList.Length; i++)
            {
                var item = gatewayList[i];
                port = item.Value<int>("InnerPort");
                long gateServerId = item.Value<int>("Id");
                NetClient gateClient = new NetClient();
                gateClient.Config(_managerGateway, ip, port, connectionCount, bufferSize, gateServerId, localGameId);
                gateClient.Start();
                gateClient.ShowPrompt();
            }

            var loginConfig = serverConfig["LoginServer"];
            ip = loginConfig.Value<string>("Ip");
            port = loginConfig.Value<int>("Port");
            long loginServerId = loginConfig.Value<long>("Id");

            _clientLogin = new NetClient();
            _clientLogin.Config(_managerLogin, ip, port, connectionCount, bufferSize, loginServerId, localGameId);
            _clientLogin.Start();
            _clientLogin.ShowPrompt();

            var worldConfig = serverConfig["WorldServer"];
            ip = worldConfig.Value<string>("Ip");
            port = worldConfig.Value<int>("Port");
            long worldServerId = worldConfig.Value<long>("Id");

            _clientWorld = new NetClient();
            _clientWorld.Config(_managerWorld, ip, port, connectionCount, bufferSize, worldServerId, localGameId);
            _clientWorld.Start();
            _clientWorld.ShowPrompt();

            NetNodeReconnect.Instance.Init();
        }

        public void Run()
        {
            _managerDatabase.DoNetMessages();
            _managerGateway.DoNetMessages();
            _managerLogin.DoNetMessages();
            _managerWorld.DoNetMessages();
            _managerGM.DoNetMessages();
        }

        public void Stop()
        {
            NetNodeReconnect.Instance.Release();

            _managerDatabase.StopNetwork();
            _managerGateway.StopNetwork();
            _managerGM.StopNetwork();
            _managerLogin.StopNetwork();
            _managerWorld.StopNetwork();
        }

        public void Release()
        {
        }
    }
}
